//
// Copyright (c) 2011, Peter Lane
// Licensed under the Academic Free License version 3.0

package fan.swtChartWrapper;

import fan.fwt.*;
import fan.fwt.Prop;
import fan.sys.*;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtchart.*;
import org.eclipse.swtchart.Chart;
import fan.sys.List;
import java.util.ArrayList;
import fan.gfx.Color;
import fan.gfx.Orientation;

public class ChartPeer extends CanvasPeer {

  //////////////////////////////////////////////////////////////////////////
  // Construction
  //////////////////////////////////////////////////////////////////////////

  public static ChartPeer make (fan.swtChartWrapper.Chart self) throws Exception {
    ChartPeer peer = new ChartPeer ();
    ((fan.fwt.Widget)self).peer = peer;
    peer.self = self;

    // make title font a bit bigger, by default
    Title myTitle = peer.title(self);
    myTitle.peer.font (myTitle, myTitle.peer.font(myTitle).toSize (13));

    return peer;
  }

  Chart _chart;
  public Widget create (Widget parent) {
    _chart = new Chart((Composite)parent, SWT.NONE);
    _xAxis.peer.setChartAxis (_chart, _chart.getAxisSet().getXAxis (0));
    _yAxis.peer.setChartAxis (_chart, _chart.getAxisSet().getYAxis (0));

    ISeriesSet seriesSet = _chart.getSeriesSet();
    for (int i = 0; i < _dataSeries.size (); ++i) {
      Series theSeries = (Series)(_dataSeries.get (i));
      if (theSeries instanceof LineSeries) {
        LineSeries series = (LineSeries)theSeries;
        ISeries iseries = seriesSet.createSeries(series.peer.type (), series.label ());
        series.peer.setISeries (iseries);
      } else if (theSeries instanceof BarSeries) {
        BarSeries series = (BarSeries)theSeries;
        ISeries iseries = seriesSet.createSeries(series.peer.type (), series.label ());
        series.peer.setISeries (iseries);
      } else if (theSeries instanceof ScatterSeries) {
        ScatterSeries series = (ScatterSeries)theSeries;
        ILineSeries iseries = (ILineSeries)seriesSet.createSeries(series.peer.type (), series.label ());
        series.peer.setISeries (iseries);
      } else {
        System.out.println ("Ignoring series");
      }
    }
    // make sure everything can be seen, unless ranges set manually
    if (_xAxis.peer.rangeUnset()) _chart.getAxisSet().getXAxis(0).adjustRange ();
    if (_yAxis.peer.rangeUnset()) _chart.getAxisSet().getYAxis(0).adjustRange ();

    return _chart;
  }

  public void adjustRange (fan.swtChartWrapper.Chart self) { 
    _chart.getAxisSet().adjustRange (); 
    _chart.redraw ();
  }
  public void zoomIn (fan.swtChartWrapper.Chart self) { 
    _chart.getAxisSet().zoomIn (); 
    _chart.redraw ();
  }
  public void zoomOut (fan.swtChartWrapper.Chart self) { 
    _chart.getAxisSet().zoomOut (); 
    _chart.redraw ();
  }
  public void save (fan.swtChartWrapper.Chart self, String filename, ImageType format) {
    _chart.save (filename, Utility.toSwt (format));
  }

  private List _dataSeries = null;

  public void data (fan.swtChartWrapper.Chart self, List series) {
    _dataSeries = series;
  }

  // Title title := ""
  public Title title (fan.swtChartWrapper.Chart self) { return (Title)title.get (); }
  public void title (fan.swtChartWrapper.Chart self, Object o) {} // ignore setter

  class TitleProp extends Prop {
    WidgetPeer peer;
    TitleProp (WidgetPeer peer) {
      super (peer);
      this.peer = peer;
    }
    private Title val = Title.make ();
    public void syncToControl() { 
      Chart chart = (Chart)(peer.control ());
      val.peer.setITitle (chart.getTitle ()); // sets peer to point to this chart, on construction of chart
    }
    public void syncFromControl() {
    }
    public Title get () { return val; }
    public void set (Object v) {} // do nothing on 'set'
  }
  
  public final TitleProp title = new TitleProp (this);

  public Legend legend (fan.swtChartWrapper.Chart self) { return (Legend)legend.get (); }

  class LegendProp extends Prop {
    WidgetPeer peer;
    LegendProp (WidgetPeer peer) {
      super (peer);
      this.peer = peer;
    }
    private Legend val = Legend.make ();
    public void syncToControl() { 
      Chart chart = (Chart)(peer.control ());
      val.peer.setILegend (chart.getLegend ()); // sets peer to point to this chart, on construction of chart
    }
    public void syncFromControl() {
    }
    public Legend get () { return val; }
    public void set (Object v) {} // ignore this
  }

  public final LegendProp legend = new LegendProp(this);

  private Axis _xAxis = Axis.make ();
  public Axis xAxis (fan.swtChartWrapper.Chart self) { return _xAxis; }
  public void xAxis (fan.swtChartWrapper.Chart self, Axis a) {} // ignore this

  private Axis _yAxis = Axis.make ();
  public Axis yAxis (fan.swtChartWrapper.Chart self) { return _yAxis; }
  public void yAxis (fan.swtChartWrapper.Chart self, Axis a) {} // ignore this

  // Color background
  public Color background (fan.swtChartWrapper.Chart self) { return background.get(); }
  public void background (fan.swtChartWrapper.Chart self, Color v) { background.set(v); }
  public final Prop.ColorProp background = new Prop.ColorProp(this)
  {
    public fan.gfx.Color get(Widget w) { return plotBackground.get (); }
    public void set(Widget w, org.eclipse.swt.graphics.Color v) { 
      ((Chart)w).setBackground(v); 
    }
  };
  
  // Color plotBackground 
  public Color plotBackground (fan.swtChartWrapper.Chart self) { return plotBackground.get(); }
  public void plotBackground (fan.swtChartWrapper.Chart self, Color v) { plotBackground.set(v); }
  public final Prop.ColorProp plotBackground = new Prop.ColorProp(this)
  {
    public fan.gfx.Color get(Widget w) { return plotBackground.get (); }
    public void set(Widget w, org.eclipse.swt.graphics.Color v) { 
      ((Chart)w).setBackgroundInPlotArea(v); 
    }
  };

  // Orientation orientation
  public Orientation orientation (fan.swtChartWrapper.Chart self) { 
    return (orientation.get() == SWT.HORIZONTAL ? Orientation.horizontal : Orientation.vertical); 
  }
  public void orientation (fan.swtChartWrapper.Chart self, Orientation v) { 
    orientation.set (new Long(v == Orientation.horizontal ? SWT.HORIZONTAL : SWT.VERTICAL));
  }
  public final Prop.IntProp orientation = new Prop.IntProp(this, SWT.HORIZONTAL)
  {
    public int get(Widget w) { return ((Chart)w).getOrientation(); }
    public void set(Widget w, int v) {
      ((Chart)w).setOrientation (v);
    }
  };
}
